#include "cv.h"
#include "highgui.h"
#include "motrecreader.h"
#include "movseq.h"
#include "coordtrans.h"
#include "facedetect.h"
#include "skindetector.h"
#include "motiondetect.h"
#include "meanshift.h"
#include <time.h>
#include <iostream>

#define MOTFILE	"example.mot"

     
CvRect selection;   
CvPoint origin;   
bool select_object = false;
bool track_object = false;   
bool new_selection = false;
CvSize frame_size;
void on_mouse(int event, int x, int y, int flags, void *param)   
{   

    //if( image->origin )   
    //y = frame_size.height - y;   
    
    if( select_object )   
    {   
        selection.x = MIN(x,origin.x);   
        selection.y = MIN(y,origin.y);   
        selection.width = selection.x + CV_IABS(x - origin.x);   
        selection.height = selection.y + CV_IABS(y - origin.y);   
        
        selection.x = MAX( selection.x, 0 );   
        selection.y = MAX( selection.y, 0 );   
        selection.width = MIN( selection.width, frame_size.width );   
        selection.height = MIN( selection.height, frame_size.height );   
        selection.width -= selection.x;   
        selection.height -= selection.y;   
    }   
    
    switch( event )   
    {   
        case CV_EVENT_LBUTTONDOWN:   
            origin = cvPoint(x,y);   
            selection = cvRect(x,y,0,0);   
            select_object = true;   
            track_object = false;
            break;   
        case CV_EVENT_LBUTTONUP:   
            select_object = false;   
            printf("selection: (%d,%d) - (%d,%d) ", selection.x, selection.y, selection.width, selection.height);
            if( selection.width > 0 && selection.height > 0 )   {
                track_object = true;   
                new_selection = true;
            }
            break;   
    }   
    
}   


int main(int argc, char** argv)
{
    CvCapture* capture = 0;


	MotionRecordReader mrr(MOTFILE);
	CoordinateTransformer ctr;
	MovementSequence movseq;
	std::list<Movement> mov_list;

	SkinDetector *skin_detect;
	time_t start_time;
	int current_time, ret;

	skin_detect = NULL;

    
    if( argc == 1 || (argc == 2 && strlen(argv[1]) == 1 && isdigit(argv[1][0])))
        capture = cvCaptureFromCAM( argc == 2 ? argv[1][0] - '0' : 0 );
    else if( argc == 2 )
        capture = cvCaptureFromAVI( argv[1] );

    if( !capture ) {
        fprintf(stderr,"Could not initialize capturing...\n");
        return -1;
    }

    printf( "Hot keys: \n"
        "\tESC - quit the program\n"
		);

    cvNamedWindow( "woochymain", 1 ); 

	CvFont default_font = cvFont(5, 10);
	Mhi *mhi;
    
    
    IplImage *frame = 0;
    frame = cvQueryFrame(capture);
    if (!frame) {
        printf("Cannot capture image!\n");
        exit(1);
    }    
    cvFlip(frame, NULL, 1);

    frame_size = cvGetSize(frame);
    printf("Size: %d, %d\n", frame_size.width, frame_size.height);
    // hand tracking
    cvShowImage( "woochymain", frame);  
    cvSetMouseCallback( "woochymain",on_mouse, 0 );   

    MeanShift meanshift(frame_size);
    

    skin_detect = new SkinDetector(frame_size);
    mhi = new Mhi(frame_size);
    
    while (1) {
        
		int c;
        frame = cvQueryFrame(capture);
		cvFlip(frame, NULL, 1);

        skin_detect->run(frame);
        mhi->update_image(skin_detect->getMask());
        mhi->show();
        printf("OK3 \n");

		/*
		ctr.mark_face(frame);
		default_font = cvFont(1.5, 2);
		cvPutText(frame, "Press ESC if your face is correctly detected",
			cvPoint(10,100), &default_font, CV_RGB(255,0,0));	
		*/
        
        //// start hand tracking
        if( select_object &&  selection.width > 0 && selection.height > 0 )   
        {   
            cvSetImageROI( frame, selection );   
            cvXorS( frame, cvScalarAll(255), frame, 0 );   
            cvResetImageROI( frame );   
        }
        
        if (new_selection) {
            printf("initializing Meanshift\n");
            meanshift.init(frame, selection);
            
            new_selection = false;
        }
        if (track_object) {
            meanshift.run(frame);
        }
        //// end hand tracking
        
        
        cvShowImage( "woochymain", frame);
        c = cvWaitKey(10);
        if((char)c == 27 )
            break;
        
    }
        
	start_time = time(NULL);
	default_font = cvFont(5, 10);
	while (1) {
        IplImage *frame = 0;
		int c;

		current_time = time(NULL) - start_time;
#ifdef DEBUG
		printf("===========================\n");
		printf("Current Time: %d\n", current_time);
#endif
		mov_list.clear();

        frame = cvQueryFrame(capture);
        if(!frame)
            break;
		cvFlip(frame, NULL, 1);

		ret = mrr.read_next_movement_list(mov_list, current_time);
		ctr.coord_convert(mov_list, frame);
		movseq.update(current_time, mov_list);
		if (0 == movseq.size() && ret < 0) {
			cvPutText(frame, "FINISH!", cvPoint(100,100), &default_font,
				   CV_RGB(255,0,0));	
		}
		movseq.draw_movs(current_time, frame);
        cvShowImage( "woochymain", frame);
        c = cvWaitKey(10);
        if( (char) c == 27 )
            break;
	}
	cvReleaseCapture( &capture );
    cvDestroyWindow("woochymain");
    return 0;
}

